using System;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using Assets;
using Hearthstone.DataModels;
using PegasusLettuce;

namespace Mercenary
{
    public static class TaskUtils
    {
        private static List<Task> tasks = new List<Task>();

        private static Dictionary<string, MercenaryEntity> dict_skillsTargetType =
            new Dictionary<string, MercenaryEntity>();

        public static bool HaveTaskTank { get; set; }

        public static bool HaveTaskFighter { get; set; }

        public static bool HaveTaskCaster { get; set; }

        public static bool HaveTaskDocter { get; set; }

        public static void ClearTaskSpecialNode()
        {
            HaveTaskDocter = false;
            HaveTaskTank = false;
            HaveTaskFighter = false;
            HaveTaskCaster = false;
        }

        public static void UpdateMercTask()
        {
            ClearTaskSpecialNode();
            UpdateTaskInfo(GetLatestTasks());
        }

        public static void UpdateMainLineTask()
        {
            UpdateTaskInfo(GetMainLineTask());
        }

        public static void DismissTask(int taskId)
        {
            VisitorTaskDbfRecord taskRecordByID =
                LettuceVillageDataUtil.GetTaskRecordByID(taskId);
            if (taskRecordByID != null)
            {
                int mercenaryVisitorId = taskRecordByID.MercenaryVisitorId;
                Network.Get().DismissMercenaryTask(mercenaryVisitorId);
            }
        }

        public static List<Task> GetLatestTasks()
        {
            NetCache.NetCacheMercenariesVillageVisitorInfo netObject = NetCache.Get().GetNetObject<NetCache.NetCacheMercenariesVillageVisitorInfo>();
            List<Task> list = new List<Task>();
            // 因为新任务是添加在第一条，所以倒序做任务，先进先做
            for (int i = netObject.VisitorStates.Count; i > 0; --i)
            {
                MercenaryVillageTaskItemDataModel mercenaryVillageTaskItemDataModel = LettuceVillageDataUtil.CreateTaskModelFromTaskState(
                    netObject.VisitorStates[i - 1].ActiveTaskState, null);
                VisitorTaskDbfRecord taskRecordByID = LettuceVillageDataUtil.GetTaskRecordByID(netObject.VisitorStates[i - 1].ActiveTaskState.TaskId);
                // 				if ((MercenaryVisitor.VillageVisitorType)Traverse.Create(LettuceVillageDataUtil.GetVisitorRecordByID(taskRecordByID.MercenaryVisitorId)).Field("m_visitorType").GetValue() == MercenaryVisitor.VillageVisitorType.STANDARD)
                if (mercenaryVillageTaskItemDataModel.TaskType ==
                    MercenaryVisitor.VillageVisitorType.STANDARD)
                {
                    SetTask(taskRecordByID, list, mercenaryVillageTaskItemDataModel.ProgressMessage);
                }
            }
            return list;
        }

        public static List<Task> GetMainLineTask()
        {
            List<Task> list = new List<Task>();
            foreach (MercenariesVisitorState mercenariesVisitorState in 
                NetCache.Get().GetNetObject<NetCache.NetCacheMercenariesVillageVisitorInfo>().VisitorStates)
            {
                MercenaryVillageTaskItemDataModel mercenaryVillageTaskItemDataModel =
                    LettuceVillageDataUtil.CreateTaskModelFromTaskState(
                        mercenariesVisitorState.ActiveTaskState, null);
                if (mercenaryVillageTaskItemDataModel.TaskType == 
                    MercenaryVisitor.VillageVisitorType.SPECIAL)
                {
                    TaskAdapter.SetMainLineTask(list, mercenaryVillageTaskItemDataModel.Description);
                    break;
                }
            }
            return list;
        }

        private static void SetTask(VisitorTaskDbfRecord task,
            List<Task> tasks, string progressMessage)
        {
            MercenaryVisitorDbfRecord visitorRecordByID =
                LettuceVillageDataUtil.GetVisitorRecordByID(task.MercenaryVisitorId);
            TaskAdapter.SetTask(((DbfRecord)task).ID, visitorRecordByID.MercenaryId,
                task.TaskTitle.GetString(Locale.zhCN),
                task.TaskDescription.GetString(Locale.zhCN), tasks, progressMessage);
        }

        public static long Current()
        {
            return new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
        }

        private static void UpdateTaskInfo(List<Task> newTasks)
        {
            using (List<Task>.Enumerator enumerator = newTasks.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    Task task_new = enumerator.Current;
                    Task task_old = tasks.Find((Task x) => x.Id == task_new.Id &&
                        x.ProgressMessage == task_new.ProgressMessage);
                    task_new.StartAt = ((task_old != null) ? task_old.StartAt : Current());
                }
            }
            tasks = newTasks;
            dict_skillsTargetType = GetTaskSkillAndTargetType(tasks);
        }

        public static bool HasSkill(string skill)
        {
            return dict_skillsTargetType.ContainsKey(skill);
        }

        public static TARGETTYPE FindSkillTargetType(string skill)
        {
            if (!dict_skillsTargetType.ContainsKey(skill))
            {
                return TARGETTYPE.UNSPECIFIED;
            }
            return dict_skillsTargetType[skill].TargetType;
        }

        public static int FindSkillSubskillIndex(string skill)
        {
            if (!dict_skillsTargetType.ContainsKey(skill))
            {
                return -1;
            }
            return dict_skillsTargetType[skill].SubSkillIndex;
        }

        public static List<Task> GetTaskList()
        {
            return (from t in tasks orderby t.Priority, t.water select t).ToList();
        }

        private static List<MercenaryEntity> GetTaskMercenaries(List<Task> allTasks)
        {
            List<MercenaryEntity> list = new List<MercenaryEntity>();
            foreach (Task allTask in allTasks)
            {
                if(allTask.Mercenaries!=null)
                {
                    foreach (MercenaryEntity mercenary in allTask.Mercenaries)
                    {
                        list.Add(mercenary);
                    }
                }
            }
            return list;
        }

        private static Dictionary<string, MercenaryEntity> GetTaskSkillAndTargetType(
            List<Task> allTasks)
        {
            Dictionary<string, MercenaryEntity> dictionary =
                new Dictionary<string, MercenaryEntity>();
            foreach (MercenaryEntity item in GetTaskMercenaries(allTasks))
            {
                if (!string.IsNullOrEmpty(item.Skill) && !dictionary.ContainsKey(item.Skill))
                {
                    dictionary.Add(item.Skill, item);
                }
            }
            return dictionary;
        }

        public static bool HasIdleTask()
        {
            int currentTierPropertyForBuilding = 
                LettuceVillageDataUtil.GetCurrentTierPropertyForBuilding(
                    MercenaryBuilding.Mercenarybuildingtype.TASKBOARD, TierProperties.Buildingtierproperty.TASKSLOTS, null);
            UtilsLog.Log($"已构建={currentTierPropertyForBuilding} " +
                $"佣兵任务={LettuceVillageDataUtil.VisitorStates.Count}");
            return 2 + currentTierPropertyForBuilding - LettuceVillageDataUtil.VisitorStates.Count > 0;
        }
    }
}
